package cn.demoncat.util.disruptor;

import com.lmax.disruptor.RingBuffer;

import cn.demoncat.util.lang.BeanUtil;

/**
 * Event 生产者 - 通用基类
 * <pre>
 * 适用：缓存数据==构建数据
 * 说明：可以参考构建，非必须继承
 * 
 * T：Event数据类型
 * A：Event构建参数类型
 * </pre>
 * @author 延晓磊
 *
 * @since 2020年1月2日
 */
public class EventProducer<T,A> {

	/**
	 * 环形缓冲区
	 */
	protected final RingBuffer<T> ringBuffer;

	/**
	 * 初始化Event生产者
	 * 
	 * @param ringBuffer	环形缓冲区
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年1月2日
	 */
	public EventProducer(RingBuffer<T> ringBuffer) {
		this.ringBuffer = ringBuffer;
	}

	/**
	 * 发布Event
	 * 
	 * @param input	Event数据构建参数
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年1月2日
	 */
	public void onData(A input) {
		// 获取序列号
		long sequence = ringBuffer.next();
		// 获取Event
		T event = ringBuffer.get(sequence);
		// 设置Event
		setEvent(event, input);
		// 发布Event
		ringBuffer.publish(sequence);
	}
	
	/**
	 * 设置Event
	 * <br/>
	 * 默认通过BeanUtils.copyProperties拷贝，子类可以重写本方法
	 * 
	 * @param event	Event数据
	 * @param arg	设置参数
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年1月8日
	 */
	protected void setEvent(T event, A arg) {
		BeanUtil.copy(arg, event);
	}
	
}
